package com.tunan.lsj.interceptor;

import java.io.IOException;
import java.util.Calendar;
import java.util.Optional;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.tunan.persistence.model.TSysUserLoginTn;
import com.tunan.system.service.SysUserLoginService;
import com.tunan.system.service.TokenService;
import com.tunan.utils.DateUtils;
import com.tunan.utils.RedisUtils;

import redis.clients.jedis.exceptions.JedisException;

/**
 * 拦截Token过期的请求
 * 
 * @author janice
 *
 */
public class TokenSecurityInterceptor extends HandlerInterceptorAdapter {

	Logger logger = LoggerFactory.getLogger(TokenSecurityInterceptor.class);

	@Autowired
	private RedisUtils redisUtils;

	@Autowired
	private TokenService tokenService;

	@Autowired(required = false)
	private SysUserLoginService sysUserLoginService;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		Optional<String> accessToken = Optional.ofNullable(request.getParameter("accessToken"));
		if (!accessToken.isPresent()) {
			accessToken = Optional.ofNullable(request.getHeader("accessToken"));
		}

		Optional<TSysUserLoginTn> user = Optional.empty();

		if (!redisUtils.isRedisLived()) {
			user = selectByToken(accessToken);
			Calendar userLoginTime = Calendar.getInstance();
			userLoginTime.setTime(user.get().getDeadline());
			if (user.isPresent() && userLoginTime.after(Calendar.getInstance())) {
				return true;
			} else {
				return disabledToken(request, response);
			}
		}
		try {
			if (tokenService.checkToken(accessToken.get())) {
				return true;
			} else if (tokenService.checkToken(accessToken.get() + "_")) {
				if (tokenService.changToken(accessToken.get()+"_") == null) {
					tokenService.delFreshToken(accessToken.get());
					return disabledToken(request, response);
				}
				return true;
			}
			return disabledToken(request, response);
		} catch (JedisException e) {
			if (logger.isDebugEnabled()) {
				logger.debug("{},redis服务器不能访问", DateUtils.getCurrentDate());
			}
			synchronized (this) {
				if (redisUtils.isRedisLived()) {
					redisUtils.setRedisLived(false);
					;
				}
			}
			return selectByToken(accessToken).isPresent();
		}
	}

	private boolean disabledToken(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.getRequestDispatcher("/loginController/staleToken/").forward(request, response);
		return false;
	}

	private Optional<TSysUserLoginTn> selectByToken(Optional<String> accessToken) {
		return sysUserLoginService.selectByToken(accessToken.get());
	}
}
